/*
 * 实时任务功能模块 V 0.2
 * 作者:basncy c@basncy.com
 */
 

#include "usbctrl.h"
#include "../include/uptaskr.h"


static sem_t		*uptaskrsem;	/* 信号量 */
static pthread_mutex_t	 uptaskrmutex=PTHREAD_MUTEX_INITIALIZER;	/* 互斥锁 */
static struct uptaskr	*uptaskrptr;	/* 指向共享内存区的指针 */

/*
 * 初始化实时任务队列
 */
int
initutr()
{
  //初始化共享内存
  uptaskrptr	       = (struct uptaskr *)mmap(NULL,sizeof(struct uptaskr), PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANON,-1,0);
  uptaskrptr->front = 0;
  uptaskrptr->rear  = 0;
  uptaskrptr->nfree=MAXCLIENTS;

  //初始化信号量
  uptaskrsem = sem_open("/uptaskrsem", O_CREAT | O_RDWR, FILE_MODE, 0);
  sem_init(uptaskrsem,1,0);
  
  //初始化互斥锁.static声明时已经初始化
  //  memset(&uptaskrmutex,0,sizeof(pthread_mutex_t));
  return 0;
}

/*
 * 添加一个新的实时任务,插入到链表尾
 * newcmd: 新任务
 * 返回：0成功 -1失败
 */
int
addutr(const struct upcmd newcmd)
{
  /* 将新任务添加到队首 */
  pthread_mutex_lock(&uptaskrmutex);

  if(uptaskrptr->nfree <= 0){
    /* 队满，添加失败 */
    pthread_mutex_unlock(&uptaskrmutex);
    return -1;
  }

  uptaskrptr->front = (uptaskrptr->front+1)%MAXCLIENTS;
  memcpy(&uptaskrptr->utr_upcmds[uptaskrptr->front],&newcmd,sizeof(struct upcmd));
  uptaskrptr->nfree--;
  
  pthread_mutex_unlock(&uptaskrmutex);
  sem_post(uptaskrsem);

  return 0;
}


/*
 * 从队首取出一个任务
 * cmd: 保存返回的任务
 * 返回 成功0
 */
int
getutr(struct upcmd *cmd)
{
  struct uptaskr	*utrdel;
  sem_wait(uptaskrsem);
  
  pthread_mutex_lock(&uptaskrmutex);
  /* 从队尾取出数据 */
  uptaskrptr->rear = (uptaskrptr->rear+1)%MAXCLIENTS;
  memcpy(cmd, &uptaskrptr->utr_upcmds[uptaskrptr->rear],sizeof(struct upcmd));
  uptaskrptr->nfree++;
  
  pthread_mutex_unlock(&uptaskrmutex);
  
  return 0;
}

/*
 * 关闭实时队列
 */
void
closeutr()
{
  sem_destroy(uptaskrsem);
  munmap(uptaskrptr,,sizeof(struct uptaskr));
}
